#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <U8g2lib.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Adafruit_AHTX0.h> //AHT20
Adafruit_AHTX0 AHT;
#include <NTPClient.h>                  // 引入NTPClient库文件，用于NTP时间同步
const char *ntpServer = "pool.ntp.org"; // 默认NTP服务器
const long gmtOffset_sec = 28800;       // 北京时间 (UTC+8) 的时区偏移量
const int daylightOffset_sec = 0;       // 不考虑夏令时
WiFiUDP udp;                            // 用于NTP时间同步的UDP客户端对象
NTPClient timeClient(udp, ntpServer, gmtOffset_sec, 60000);
const char *ssid = "styn-iot";
const char *password = "st7713926813";
TaskHandle_t Task1;
TaskHandle_t Task2;
String response;
String shijian;
int year;                                                                                        // 获取年份
int month;                                                                                       // 获取月份，月份从0开始，所以加1 // 月份从 0 开始
int day;                                                                                         // 获取日期
int hour;                                                                                        // 获取小时
int minute;                                                                                      // 获取分钟
int second;                                                                                      // 获取秒
float Temperature = 0.0;                                                                         // 温度变量
float Humidity = 0.0;                                                                            // 湿度变量
U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, /* clock=*/18, /* data=*/23, /* cs=*/5, /* reset=*/2); // 根据你的接线调整
void TaskFunction1(void *pr)
{
  timeClient.begin(); // 初始化timeClient对象
  while (1)
  {
    timeClient.update();                                 // 获取并更新时间
    unsigned long epochTime = timeClient.getEpochTime(); // 获取时间戳
    struct tm *ptm = gmtime((time_t *)&epochTime);       // 将时间戳转换为tm结构体
    year = ptm->tm_year + 1900;                          // 获取年份
    month = ptm->tm_mon + 1;                             // 获取月份，月份从0开始，所以加1 // 月份从 0 开始
    day = ptm->tm_mday;                                  // 获取日期
    hour = timeClient.getHours();                        // 获取小时
    minute = timeClient.getMinutes();                    // 获取分钟
    second = timeClient.getSeconds();                    // 获取秒
    vTaskDelay(1000);
  }
}
void TaskFunction2(void *pr)
{
  vTaskDelay(5000 / portTICK_PERIOD_MS);
  u8g2.begin();
  
  // 预先分配字符缓冲区，避免频繁创建String对象
  char timeStr[20];
  char timeStr1[20];
  char timeStr2[20];
  char timeStr3[20];
  
  while (1) {
    // 使用snprintf格式化字符串，更安全高效
    snprintf(timeStr, sizeof(timeStr), "%d/%02d/%02d", year, month, day);
    snprintf(timeStr1, sizeof(timeStr1), "%02d:%02d:%02d", hour, minute, second);
    snprintf(timeStr2, sizeof(timeStr2), "T:%.1fC", Temperature);
    snprintf(timeStr3, sizeof(timeStr3), "H:%.1f%%", Humidity);
    
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_ncenB08_tr);
    
    // 直接使用字符数组，无需转换
    u8g2.drawStr(0, 30, timeStr);
    u8g2.drawStr(0, 40, timeStr1);
    u8g2.drawStr(0, 50, timeStr2);
    u8g2.drawStr(0, 60, timeStr3);
    
    // 时钟刻度绘制优化
    static const char* hourNumbers[] = {"12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"};
    for (int i = 0; i < 12; i++) {
      float angle = (i * 30 - 90) * DEG_TO_RAD;
      int x = 96 + cos(angle) * 28;
      int y = 36 + sin(angle) * 28;
      u8g2.drawStr(x, y, hourNumbers[i]);
    }
    
    // 时钟指针绘制优化
    float sec_angle = (second * 6 - 90) * DEG_TO_RAD;
    float min_angle = (minute * 6 - 90) * DEG_TO_RAD;
    float hour_angle = (hour % 12 * 30 + minute * 0.5 - 90) * DEG_TO_RAD;
    
    u8g2.drawLine(96, 36, 96 + cos(sec_angle) * 20, 36 + sin(sec_angle) * 20);
    u8g2.drawLine(96, 36, 96 + cos(min_angle) * 18, 36 + sin(min_angle) * 18);
    u8g2.drawLine(96, 36, 96 + cos(hour_angle) * 12, 36 + sin(hour_angle) * 12);
    
    u8g2.sendBuffer();
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
}

void setup()
{
  Serial.begin(9600);
  Wire.begin(32, 33);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("连接成功");
  Serial.print("IP 地址：");
  Serial.println(WiFi.localIP());
  // 初始化AHT传感器
  AHT.begin();
  xTaskCreate(TaskFunction1, "Task1", 10000, NULL, 1, &Task1);
  xTaskCreate(TaskFunction2, "Task2", 10000, NULL, 1, &Task2);
}
sensors_event_t humidity, temp;

void loop()
{
  // 从AHT传感器获取事件
  AHT.getEvent(&humidity, &temp);

  // 更新温度和湿度数据
  Temperature = temp.temperature - 0.86;
  Humidity = humidity.relative_humidity;
  delay(100);
}